package com.dding.cms.base.web.util;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.dding.core.log.ILogger;
import org.dding.core.log.LoggerFactory;
import org.dding.core.util.StringUtils;
import org.javalite.activejdbc.Model;

public class Utils {

	private static ILogger logger = LoggerFactory.getLogger(Utils.class);

	private static Map<String, String> mapping = new HashMap<String, String>();

	static {
		mapping.put("VARCHAR", "java.lang.String");
		mapping.put("INT", "java.lang.Integer");
		mapping.put("BIT", "java.lang.Boolean");
		mapping.put("datetime", "java.util.Date");
	}

	public static String getBoType(String name) {
		return mapping.get(name);
	}

	public static <T extends Class<?>> Object buildBO(Model model, T clazz) {
		Field[] fields = clazz.getDeclaredFields();
		Object target = null;
		try {
			target = clazz.newInstance();
		} catch (Exception e) {
			logger.warn(e, "create " + clazz.getSimpleName() + " failure.");
		}
		for (Field f : fields) {
			NoField anno = f.getAnnotation(NoField.class);
			if (anno != null)
				continue;
			Object value = model.get(f.getName());
			if (value == null)
				continue;
			PropertyDescriptor descriptor = null;
			try {
				descriptor = new PropertyDescriptor(f.getName(), clazz);
			} catch (IntrospectionException e) {
				logger.error(e);
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				logger.equals(e);
			}
			try {
				descriptor.getWriteMethod().invoke(target, value);
			} catch (Exception e) {
				logger.error(e, "handle field " + f.getName() + " failure in "
						+ clazz.getSimpleName());
			}

		}
		return target;
	}

	public static <T extends Class<?>> Map<String, Object> buildBoMap(
			Model model, T clazz) {
		Field[] fields = clazz.getDeclaredFields();
		Map<String, Object> result = new HashMap<String, Object>();
		for (Field f : fields) {
			NoField anno = f.getAnnotation(NoField.class);
			if (anno != null)
				continue;
			Object value = model.get(f.getName());
			if (value == null)
				continue;
			result.put(f.getName(), value);
		}
		return result;
	}

	public static void setBoValue(Object target, String field, Object value) {

		if (StringUtils.isEmpty(field) || value == null) {
			logger.error("Filed or value can't be null");
			return;
		}
		Field targetField;
		try {
			targetField = target.getClass().getField(field);

			NoField anno = targetField.getAnnotation(NoField.class);
			if (anno != null) {
				logger.error("Field " + field + " is annotation with NoField");
				return;
			}

		} catch (SecurityException e1) {
			logger.error(e1);
			return;
		} catch (NoSuchFieldException e1) {
			logger.error(e1);
			return;
		}

		PropertyDescriptor descriptor = null;
		try {
			descriptor = new PropertyDescriptor(targetField.getName(),
					target.getClass());
		} catch (IntrospectionException e) {
			logger.error(e);
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			logger.equals(e);
		}
		try {
			descriptor.getWriteMethod().invoke(target, value);
		} catch (Exception e) {
			logger.error(e, "handle field " + targetField.getName()
					+ " failure in " + target);
		}

	}

	public static File formatPath(String webPath, String folder) {
		File temp = new File(folder);
		boolean ok = false;
		if (temp.isAbsolute() && temp.exists()) {
			return temp;
		}
		if (!ok) {
			temp = new File(webPath, folder);
			if (temp.exists()) {
				return temp;
			} else {
				try {
					FileUtils.forceMkdir(temp);
					return temp;
				} catch (IOException e) {
					logger.error(e);
				}
			}
		}
		return null;
	}
}
